package com.ice.framework.web.config;

import lombok.CustomLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 配置输出，项目启动后打印参数
 * @author wangwei
 * @Date 2022/1/19 17:36
 */
@CustomLog
@Component
public class PropertiesLoggingConfig implements ApplicationRunner {

    @Resource
    private ConfigurableEnvironment springEnv;


    @Override
    public void run(ApplicationArguments args) throws Exception {
        MutablePropertySources propSrcs = springEnv.getPropertySources();
        //  // 获取所有配置 key -> [source, key, value]
        Map<String, String[]> props = propSrcs.stream()
                .filter(ps -> ps instanceof EnumerablePropertySource)
                .map(ps -> (EnumerablePropertySource<?>) ps)
                .flatMap(ps -> {
                            String psName = ps.getName();
                            if (psName.startsWith("applicationConfig")) {
                                psName = psName.substring(31);
                                psName = psName.substring(0, psName.length() - 1);
                            }
                            final String fpsName = psName;
                            return Arrays.stream(ps.getPropertyNames())
                                    .map(ppName -> new String[]{fpsName, ppName, getProperty(ppName)});
                        }
                )
                .distinct()
                .sorted(Comparator.comparing(pArr -> pArr[1]))
                .collect(Collectors.toMap(pArr -> pArr[1], Function.identity(), (pArr1, pArr2) -> pArr1));

        // key 和 value 之间的最小间隙
        int interval = 20;
        int max01 = props.values().stream()
//                .filter(v -> !"systemProperties".equals(v[0]) && !"systemEnvironment".equals(v[0]))
                .map(pArr -> pArr[0])
                .max(Comparator.comparingInt(String::length))
                .orElse("")
                .length();
        int max12 = props.values().stream()
//                .filter(v -> !"systemProperties".equals(v[0]) && !"systemEnvironment".equals(v[0]))
                .map(pArr -> pArr[1])
                .max(Comparator.comparingInt(String::length))
                .orElse("")
                .length();
        List<Map.Entry<String, String[]>> collect = props.entrySet().stream().collect(Collectors.toList());
        // 打印
        String propStr = props.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .filter(e -> !"systemProperties".equals(e.getValue()[0]) && !"systemEnvironment".equals(e.getValue()[0]))
                .map(e -> {
                    String[] pArr = e.getValue();
                    int i01 = max01 - pArr[0].length() + interval;
                    int i12 = max12 - pArr[1].length() + interval;
                    String p01 = String.join("", Collections.nCopies(i01, " "));
                    String p12 = String.join("", Collections.nCopies(i12, " "));
                    return pArr[0] + p01 + pArr[1] + p12 + pArr[2];
                })
                .reduce((s1, s2) -> s1 + "\n" + s2)
                .orElse("");
        logger.info("开始输出环境变量");
        logger.info("\n" + propStr);
    }

    private String getProperty(String name) {
        try {
            return springEnv.getProperty(name);
        } catch (Exception e) {
            return "";
        }
    }
}
